﻿Imports System
Imports System.CodeDom
Imports System.Collections.Generic
Imports System.ComponentModel
Imports System.Globalization
Imports System.Text
Imports System.Workflow.ComponentModel.Compiler

Namespace System.Workflow.Activities.Rules
    <Serializable> _
    Public NotInheritable Class RuleExpressionCondition
        Inherits RuleCondition
        ' Methods
        Public Sub New()
            Me._expressionLock = New Object
        End Sub

        Public Sub New(ByVal expression As CodeExpression)
            Me._expressionLock = New Object
            Me._expression = expression
        End Sub

        Public Sub New(ByVal conditionName As String)
            Me._expressionLock = New Object
            If (conditionName Is Nothing) Then
                Throw New ArgumentNullException("conditionName")
            End If
            Me._name = conditionName
        End Sub

        Public Sub New(ByVal conditionName As String, ByVal expression As CodeExpression)
            Me.New(conditionName)
            Me._expression = expression
        End Sub

        Public Overrides Function Clone() As RuleCondition
            Dim condition As RuleExpressionCondition = DirectCast(MyBase.MemberwiseClone, RuleExpressionCondition)
            condition._runtimeInitialized = False
            condition._expression = RuleExpressionWalker.Clone(Me._expression)
            Return condition
        End Function

        Public Overrides Function Equals(ByVal obj As Object) As Boolean
            Dim flag As Boolean = False
            Dim condition As RuleExpressionCondition = [TryCast](obj,RuleExpressionCondition)
            If (Not condition Is Nothing) Then
                flag = ((Me.Name = condition.Name) AndAlso (((Me._expression Is Nothing) AndAlso (condition.Expression Is Nothing)) OrElse ((Not Me._expression Is Nothing) AndAlso RuleExpressionWalker.Match(Me._expression, condition.Expression))))
            End If
            Return flag
        End Function

        Public Overrides Function Evaluate(ByVal execution As RuleExecution) As Boolean
            Return ((Me._expression Is Nothing) OrElse Executor.EvaluateBool(Me._expression, execution))
        End Function

        Public Overrides Function GetDependencies(ByVal validation As RuleValidation) As ICollection([Of] String)
            Dim analysis As New RuleAnalysis(validation, False)
            If (Not Me._expression Is Nothing) Then
                RuleExpressionWalker.AnalyzeUsage(analysis, Me._expression, True, False, Nothing)
            End If
            Return analysis.GetSymbols
        End Function

        Public Overrides Function GetHashCode() As Integer
            Return MyBase.GetHashCode
        End Function

        Public Overrides Sub OnRuntimeInitialized()
            If Not Me._runtimeInitialized Then
                Me._runtimeInitialized = True
            End If
        End Sub

        Public Overrides Function ToString() As String
            If (Not Me._expression Is Nothing) Then
                Dim stringBuilder As New StringBuilder
                RuleExpressionWalker.Decompile(stringBuilder, Me._expression, Nothing)
                Return stringBuilder.ToString
            End If
            Return ""
        End Function

        Public Overrides Function Validate(ByVal validation As RuleValidation) As Boolean
            If (validation Is Nothing) Then
                Throw New ArgumentNullException("validation")
            End If
            Dim flag As Boolean = True
            If (Me._expression Is Nothing) Then
                flag = False
                Dim error As New ValidationError(String.Format(CultureInfo.CurrentCulture, Messages.ConditionExpressionNull, New Object() { GetType(CodePrimitiveExpression).ToString }), 400)
                [error].UserData.Item("ErrorObject") = Me
                validation.AddError([error])
                Return flag
            End If
            Return validation.ValidateConditionExpression(Me._expression)
        End Function


        ' Properties
        <DesignerSerializationVisibility(DesignerSerializationVisibility.Content)> _
        Public Property Expression As CodeExpression
            Get
                Return Me._expression
            End Get
            Set(ByVal value As CodeExpression)
                If Me._runtimeInitialized Then
                    Throw New InvalidOperationException(SR.GetString("Error_CanNotChangeAtRuntime"))
                End If
                SyncLock Me._expressionLock
                    Me._expression = value
                End SyncLock
            End Set
        End Property

        Public Overrides Property Name As String
            Get
                Return Me._name
            End Get
            Set(ByVal value As String)
                If Me._runtimeInitialized Then
                    Throw New InvalidOperationException(SR.GetString("Error_CanNotChangeAtRuntime"))
                End If
                Me._name = value
            End Set
        End Property


        ' Fields
        Private _expression As CodeExpression
        <NonSerialized> _
        Private _expressionLock As Object
        Private _name As String
        Private _runtimeInitialized As Boolean
    End Class
End Namespace

